<template>
  <div class="upload-demo">
    <div class="upload-box">
      <el-upload class="upload-demo" action="" :before-upload="beforeUpload">
        <el-button size="small" slot="trigger">选择文件</el-button>
      </el-upload>
    </div>

    <div class="file" v-if="file">
      <p>
        文件：<a :href="downloadUrl" target="_blank">{{ file.name }}</a>
      </p>
      <div class="progress" v-show="progress">
        进度：<el-progress :percentage="progress"></el-progress>
      </div>
    </div>

    <div class="actions">
      <el-button
        size="small"
        type="primary"
        v-if="status === 'ready'"
        :disabled="!tusUpload"
        @click="upload"
        >开始上传</el-button
      >
      <el-button
        size="small"
        type="primary"
        v-else-if="status === 'uploading'"
        @click="puase"
        >暂停</el-button
      >
      <el-button
        size="small"
        type="primary"
        v-if="status === 'puased'"
        @click="resume"
        >继续上传</el-button
      >
    </div>
    <div class="previous" v-if="showPreviousUploads">
      <p class="tip">该文件已上传过一部分，是否继续？</p>
      <el-button size="small" @click="goon">继续</el-button>
      <el-button size="small" @click="refreshUpload" type="primary"
        >重新上传</el-button
      >
    </div>
  </div>
</template>

<script>
import * as tus from "tus-js-client";
// import SparkMD5 from "spark-md5";
// const url = "https://tusd.tusdemo.net/files/";
// const url = "http://192.168.199.23:9090/files/ios/";
const url = "http://localhost:3333/files/";
const threeHoursAgo = Date.now() - 3 * 60 * 60 * 1000;
export default {
  name: "UploadDemo",
  data() {
    return {
      progress: 0,
      file: null,
      status: "ready",
      tusUpload: null,
      previousUploads: [],
      showPreviousUploads: false,
      downloadUrl: "",
    };
  },
  methods: {
    beforeUpload(file) {
      this.file = file;
      this.downloadUrl = "";
      this.reset();
      this.initTus(file);
      return false;
    },
    initTus(file) {
      const fileReader = new FileReader();
      fileReader.readAsArrayBuffer(file);
      fileReader.onload = (event) => {
        console.log("fileReader>>>", event.target.result);
        // const spark = new SparkMD5.ArrayBuffer();
        // spark.append(event.target.result);
        // const md5Hash = spark.end();
        const options = {
          endpoint: url,
          metadata: {
            filename: file.name,
            filetype: file.type,
            // taskId: "sd45a5a4d",
            // token: "3f1e54cd-5910-4343-bd6e-02cae5afcdb1",
            // source: "backend",
            // asset_id: "2",
            // udid: "shdhj55445555",
            // md5: md5Hash,
          },
          // addRequestId: true, // todo: 可选
        };

        const newUpload = new tus.Upload(file, options);
        this.tusUpload = newUpload;
      };
    },
    async upload() {
      if (!this.tusUpload) return;

      // 每中断一次都会记录下来，metadata 时间等信息
      const allPreviousUploads = await this.tusUpload.findPreviousUploads();
      console.log("allPreviousUploads", allPreviousUploads);
      // 过滤出三小时内的上传
      const lastThreeHrsPrevUploads = allPreviousUploads
        .filter(
          (upload) => new Date(upload.creationTime).getTime() > threeHoursAgo
        )
        .sort(
          (a, b) =>
            new Date(b.creationTime).getTime() -
            new Date(a.creationTime).getTime()
        );

      this.previousUploads = lastThreeHrsPrevUploads;

      if (lastThreeHrsPrevUploads.length === 0) {
        this.refreshUpload();
        return;
      }
      this.showPreviousUploads = true;
    },
    puase() {
      this.status = "puased";
      this.tusUpload.abort();
    },
    resume() {
      this.status = "uploading";
      this.tusUpload.start();
    },
    goon() {
      if (!this.tusUpload) return;
      this.tusUpload.resumeFromPreviousUpload(this.previousUploads[0]);
      this.refreshUpload();
    },
    refreshUpload() {
      if (!this.tusUpload) return;
      this.status = "uploading";
      this.tusUpload.options.onError = (error) => {
        console.log("demo: error", error);

        if (error instanceof tus.DetailedError && error.originalRequest) {
          const text = `The upload was interrupted by a network failure or server error. Usually, this failure will disappear by retrying the upload. If the error does not disappear, please contact us.

Details: ${error.message}

Do you want to retry the upload?`;

          if (window.confirm(text)) {
            this.tusUpload.start();
            return;
          }
        } else {
          window.alert("Failed because: " + error.message);
        }

        this.reset();
      };

      this.tusUpload.options.onProgress = (bytesUploaded, bytesTotal) => {
        this.progress = Math.round((bytesUploaded / bytesTotal) * 100);
      };

      this.tusUpload.options.onSuccess = () => {
        this.downloadUrl = this.tusUpload.url;
        this.reset();
      };
      this.showPreviousUploads = false;
      this.tusUpload.start();
    },
    reset() {
      this.status = "ready";
      this.progress = 0;
      this.tusUpload = null;
    },
  },
};
</script>

<style scoped>
.upload-demo .upload-box {
  padding: 16px;
}
</style>
